package resources.Grafo;

import java.util.Vector;
import java.lang.String;

	public class Grafo {
	Vector<Object> enlaces;
	Vector<Object> nodos;
	
	public Vector<Object> getEnlaces() {
		return enlaces;
	}

	public void setEnlaces(Vector<Object> enlaces) {
		this.enlaces = enlaces;
	}

	public Vector<Object> getNodos() {
		return nodos;
	}

	public void setNodos(Vector<Object> nodos) {
		this.nodos = nodos;
	}

	

	public Grafo() {
		enlaces = new Vector<Object>();
		nodos = new Vector<Object>();
	}


	public void agregarNodo(Object aNodo) {
		nodos.addElement(aNodo);
	}
	
	
	public Object buscarNodo(Object aNodo) {
		int maximo = nodos.size();
		int indice = 0;
		Object salida = null;
		while (indice < maximo) {
			Object aNodoI = nodos.elementAt(indice); 
			if (aNodoI.toString().equals(aNodo.toString())) 
			{
				salida = nodos.elementAt(indice);
				indice = maximo;
			} else
				indice++;
		}
		return salida;
	}

	public Vector<Object> buscarAdyacentes(Object unNodo) {
		Vector<Object> salida = new Vector<Object>();
		for (int indice = 0; indice < enlaces.size(); indice++)
			if (((Enlace)enlaces.elementAt(indice)).inicioIguales(unNodo))
				salida.addElement(((Enlace)enlaces.elementAt(indice)).getDestino());

		return salida;
	}

	private void buscarCaminosAux(Object nodo1, Object nodo2, Vector marcados, Vector todos) {
		Vector adyacentes = this.buscarAdyacentes(nodo1);
		Vector copiaMarcados;

		for (int indice = 0; indice < adyacentes.size(); indice++) {
			if (nodo2.toString().equals(adyacentes.elementAt(indice).toString())) {
				copiaMarcados = (Vector) marcados.clone();
				copiaMarcados.addElement(nodo2);
				todos.addElement(copiaMarcados);
			} else if (!marcados.contains(adyacentes.elementAt(indice))) {
				copiaMarcados = (Vector) marcados.clone();
				copiaMarcados.addElement(adyacentes.elementAt(indice));
				this.buscarCaminosAux(adyacentes.elementAt(indice),nodo2, copiaMarcados, todos);
			}
		}

	}

	public Vector caminos(Object nodo1, Object nodo2) {
		Vector salida = new Vector();
		Vector marcados = new Vector();
		marcados.addElement(nodo1);
		this.buscarCaminosAux(nodo1, nodo2, marcados, salida);
		return salida;
	}

	public Vector listaNodos() {
		return nodos;
	}
	
	public Vector<String> imprimirNodos()
	{
		Vector <String> resultado = new Vector<String>();
		for(int i=0; i < nodos.size(); i++)
		{
			resultado.add(nodos.elementAt(i).toString());
		}
		return resultado;
	}

	public void conectar(Object origen, Object destino) {
		Object nodo1 = this.buscarNodo(origen);
		Object nodo2 = this.buscarNodo(destino);

		if ((null != nodo1) && (null != nodo2)) {
			enlaces.addElement(new Enlace(nodo1, nodo2));
			//enlaces.addElement(new Enlace(nodo2, nodo1));
		}
	}
	
	public String adyacentesAsString(String nodo) {
		Vector temp = this.buscarAdyacentes(this.buscarNodo(nodo));
		String cadena = new String(nodo + ":");
		for (int indice = 0; indice < temp.size(); indice++)
			cadena = cadena + (temp.elementAt(indice)).toString() + " ";

		return cadena;
	}

	public Vector caminosAsString(Nodo nodo1, Nodo nodo2) {
		Vector temp = this.caminos(nodo1, nodo2);
		Vector salida = new Vector();
		String cadena;

		for (int i = 0; i < temp.size(); i++) {
			cadena = new String();
			for (int j = 0; j < ((Vector) temp.elementAt(i)).size(); j++) {
				cadena = cadena + " ";
				(((Vector) temp.elementAt(i)).elementAt(j)).toString();
				salida.addElement(cadena);
			}
		}
		return salida;
	}
	
	public Vector<Vector<Object>> caminoMasCorto(Object nodo1,Object nodo2){
		
		Vector<Vector<Object>> salida = new Vector<Vector<Object>>();
		Vector<Vector<Object>> cam = new Vector<Vector<Object>>();
		
		cam=this.caminos(nodo1, nodo2);
		if(cam.isEmpty())
			return salida;
		else{
		
		salida.add(cam.elementAt(0));
		for(int i=1; i<cam.size();i++){
			if(salida.elementAt(0).size()>cam.elementAt(i).size()){
				salida.elementAt(0).addAll(cam.elementAt(i));
			}
			else{
				if(salida.elementAt(0).size()==cam.elementAt(i).size()){
					salida.addElement(cam.elementAt(i));
				}
			}
	
		}
	return salida;	
		}
	}
	
	public Vector<String> nodosSumideros(){
		
		Vector<String> nodosSumideros = new Vector<String>();
		
		for(int i=0; i<nodos.size(); i++){
			if(this.buscarAdyacentes(nodos.elementAt(i)).size() == 0){
				nodosSumideros.add(nodos.elementAt(i).toString());
			}
		}
		return nodosSumideros;
	}
	
	public Vector<Vector<Object>> ciclos(){
		
		Vector<Vector<Object>> salida = new Vector<Vector<Object>>();
		
		for(int i=0; i<nodos.size();i++)
			salida.addAll(this.caminos(nodos.elementAt(i), nodos.elementAt(i)));
		
		return salida;
	}

}
